﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Xrm.Sdk.Client;
using System.ServiceModel.Description;
using Microsoft.Xrm.Sdk.Query;
using Microsoft.Xrm.Sdk;
using System.Net;

namespace EWSEditor.CRM
{
    class CrmAuthInfoFactory
    {
        private static string _username;
        private static string _password;
        private static string _crmServiceUrl;
        public static string CrmServiceUrl
        {
            get { return _crmServiceUrl; }
        }
        private static string _targetMailbox;
        private static bool? _homeRealm;
        private static string _homeRealmDomain;
        public static bool? _targetValidated;
        public static bool AuthSuccess = false;

        public static string TargetMailbox
        { get { return _targetMailbox; } }

        private static IServiceManagement<IOrganizationService> _orgServiceManagement;
        private static AuthenticationCredentials _authcredentials;
        
        /// <summary>
        /// We store the credentials from Exchange so we can pass them over to the EWS POST Form automatically.
        /// Note: This will be null if the user has utilized oAuth.
        /// </summary>
        public static NetworkCredential ExchangeCreds;

       

        public static void SetProperties(string username, string password, string orgurl, string mailbox, bool? homerealm, string homerealmdomain)
        {
            _username = username;
            _password = password;
            //_crmServiceUrl = orgurl;
            _targetMailbox = mailbox;
            _homeRealm = homerealm;
            _homeRealmDomain = homerealmdomain;

            _crmServiceUrl = SetCrmServiceUrl(orgurl);
        }

        private static string SetCrmServiceUrl(string orgurl)
        {
            string fullSvcUrl = "";

            if (!orgurl.EndsWith("/"))
            {
                fullSvcUrl = new StringBuilder(orgurl).Append("/XrmServices/2011/organization.svc").ToString();
                return fullSvcUrl;

            }
            else
            {
                fullSvcUrl = new StringBuilder(orgurl.Substring(0, orgurl.Length - 1)).Append("XrmServices/2011/organization.svc").ToString();
                return fullSvcUrl;
            }
        }

        public static OrganizationServiceProxy GetOrgProxy()
        {
            OrganizationServiceProxy orgProxy = DoAuth();
            AuthSuccess = true;
            return orgProxy;
        }

        /// <summary>
        /// Sets up the OrganizationServiceProxy.
        /// To-Do: Add functionality to automatically refresh the token near expirey.
        /// </summary>
        /// <returns></returns>
        static OrganizationServiceProxy DoAuth()
        {
            if (_orgServiceManagement == null)
            {
                _orgServiceManagement = ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(_crmServiceUrl));
                AuthenticationCredentials authcreds = new AuthenticationCredentials();
                ClientCredentials _creds = new ClientCredentials();

                if (_username.Contains("\\"))
                {
                    int idx = _username.IndexOf("\\");
                    string domain = _username.Substring(0, idx);
                    string name = _username.Substring(idx + 1);
                    authcreds.ClientCredentials.Windows.ClientCredential = new System.Net.NetworkCredential(name, _password, domain);
                }

                else
                {
                    _creds.UserName.UserName = _username;
                    _creds.UserName.Password = _password;
                    authcreds.ClientCredentials = _creds;
                }

                if ((_homeRealm != null) && (bool)_homeRealm)
                {
                    authcreds.HomeRealm = new Uri(_homeRealmDomain);
                }

                _authcredentials = _orgServiceManagement.Authenticate(authcreds);
            }

            if (_authcredentials.SecurityTokenResponse == null)
            {
                OrganizationServiceProxy orgProxy = new OrganizationServiceProxy(_orgServiceManagement, _authcredentials.ClientCredentials);
                return orgProxy;
            }
            else
            {
                OrganizationServiceProxy orgproxy = new OrganizationServiceProxy(_orgServiceManagement, _authcredentials.SecurityTokenResponse);
                return orgproxy;
            }

            //if (_homeRealm)
            //{
            //    ClientCredentials clientcreds = new ClientCredentials();
            //    clientcreds.UserName.UserName = _username;
            //    clientcreds.UserName.Password = _password;
            //    OrganizationServiceProxy orgproxy = new OrganizationServiceProxy(new Uri(_crmServiceUrl), null, clientcreds, null);
            //    return orgproxy;
            //}
           
            //OrganizationServiceProxy proxy = new OrganizationServiceProxy(new Uri(_crmServiceUrl), new Uri(_homeRealmDomain), creds, null);
            //return proxy;
        }

        public static void ClearAuthProperties()
        {
            _username = null;
            _password = null;
            _crmServiceUrl = null;
            _targetMailbox = null;
            _homeRealm = false;
            _homeRealmDomain = null;
            _orgServiceManagement = null;
            _authcredentials = null;
            AuthSuccess = false;
            ExchangeCreds = null;
        }
    }
}
